//
//  MixSprite.cpp
//  SnowCone
//
//  Created by luotianqiang on 17/4/9.
//
//

#include "MixSprite.h"
#define STRINGIFY(A)  #A
#include "TextureMixShader.frag"
MixSprite* MixSprite::create(const Size& size){
    auto *ret = new MixSprite();
    if(ret && ret->init(size))
    {
        ret->autorelease();
        return ret;
    }
    CC_SAFE_DELETE(ret);
    return nullptr;
}

MixSprite::MixSprite(){
    currentSprite = nullptr;
    currentHeight = 0;
    downDistancef = 0.0001f;
    upDistancef =0.0001f;
    _changeDistance = 15;
}
bool MixSprite::init(const Size& pCanvasSize){
    if(!Node::init())
        return false;
    _canvasSize = pCanvasSize;
    this->setAnchorPoint(Vec2::ANCHOR_MIDDLE);
    this->setContentSize(pCanvasSize);
    return true;
}

void MixSprite::useTarget(Sprite* pTarget,float height){
    if(pTarget){
       
        if(currentSprite == nullptr|| currentSprite->getTexture() != pTarget->getTexture()){
            currentSprite = pTarget;
            this->addChild(currentSprite);
             auto glProGramState = currentSprite->getGLProgramState();
            if(glProGramState == nullptr||glProGramState->getGLProgram() == nullptr||glProGramState->getGLProgram()->getUniform("downDistancef") == nullptr) {
                auto _glProgram  = GLProgramCache::getInstance()->getGLProgram( "TextureMix");
                if(_glProgram == nullptr) {
                    _glProgram = GLProgram::createWithByteArrays(ccPositionTextureColor_noMVP_vert, TextureMixShader_frag);
                    CHECK_GL_ERROR_DEBUG();
                    GLProgramCache::getInstance()->addGLProgram(_glProgram, "TextureMix");
                }
                glProGramState = GLProgramState::create(_glProgram);
                currentSprite->setGLProgramState(glProGramState);
                glProGramState = currentSprite->getGLProgramState();
                CHECK_GL_ERROR_DEBUG();
            }
            auto tempHeight = max(currentHeight, min(_canvasSize.height,height));
            float distance = tempHeight - currentHeight;
            upDistancef = max(downDistancef, min(distance, _changeDistance)/_canvasSize.height);
            glProGramState->setUniformFloat("upDistancef", upDistancef);
            glProGramState->setUniformFloat("downDistancef", downDistancef);
            glProGramState->setUniformFloat("maxHeight", tempHeight/_canvasSize.height);
            glProGramState->setUniformFloat("minHeight", currentHeight/_canvasSize.height);
            currentHeight = tempHeight;
            downDistancef = upDistancef;
        }else {
             auto glProGramState = currentSprite->getGLProgramState();
            auto tempHeight = max(currentHeight, min(_canvasSize.height,height));
            float distance = tempHeight - currentHeight;
            upDistancef = (distance+_changeDistance)/_canvasSize.height;//max(downDistancef, min(distance, _changeDistance)/_canvasSize.height);
            glProGramState->setUniformFloat("upDistancef", upDistancef);
            glProGramState->setUniformFloat("maxHeight", tempHeight/_canvasSize.height);
            currentHeight = tempHeight;
            downDistancef = upDistancef;
        }
        
    }
}

void MixSprite::useTarget(string path,float height){
    auto s = Sprite::create(path);
    if(s) {
        s->setPosition(_canvasSize*.5);
        useTarget(s,height);
    }
}